﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace game
{
    public class ExplosionManager
    {
        private Scene scene = null;

        private Texture redExplTex;
        private Texture greenExplTex;
        private Texture stoneTex;

        protected List<ExplosionPSystem> explPSystems = new List<ExplosionPSystem>();
        protected List<ExplSmokePSystem> explSmokePSystems = new List<ExplSmokePSystem>();

        public ExplosionPSystem.Factory explPSystemFactory { get; protected set; }
        public ExplSmokePSystem.Factory explSmokePSystemFactory { get; protected set; }

        public ExplosionManager(Scene scene)
        {
            this.scene = scene;

            redExplTex = ShooterGame.Instance.Content.Load<Texture>("Textures\\6943");
            greenExplTex = ShooterGame.Instance.Content.Load<Texture>("Textures\\explosions\\expl3");
            stoneTex = ShooterGame.Instance.Content.Load<Texture>("Textures\\stone-render");

            explPSystemFactory = new ExplosionPSystem.Factory(scene, 100);
            explSmokePSystemFactory = new ExplSmokePSystem.Factory(scene, 100);
        }

        public void Update(GameTime gameTime)
        {
            for (int i = 0; i < explSmokePSystems.Count; i++)
            {
                ExplSmokePSystem system = explSmokePSystems[i];
                if (!system.IsAlive)
                {
                    explSmokePSystems.Remove(system);
                    i--;
                    explSmokePSystemFactory.Return(system);
                }
                else
                {
                    system.Update(gameTime);
                }
            }

            for (int i = 0; i < explPSystems.Count; i++)
            {
                ExplosionPSystem system = explPSystems[i];
                if (!system.IsAlive)
                {
                    explPSystems.Remove(system);
                    i--;
                    explPSystemFactory.Return(system);
                }
                else
                {
                    system.Update(gameTime);
                }
            }
        }

        public void Draw(GameTime gameTime)
        {
            foreach (ExplSmokePSystem ps in explSmokePSystems)
            {
                if (scene.ActiveCamera.Frustum.Contains(ps.GetBSphereTransformed())
                        != ContainmentType.Disjoint)
                {
                    ps.Draw(gameTime);
                }
            }

            foreach (ExplosionPSystem ps in explPSystems)
            {
                if (scene.ActiveCamera.Frustum.Contains(ps.GetBSphereTransformed())
                        != ContainmentType.Disjoint)
                {
                    ps.Draw(gameTime);
                }
            }
        }

        public void SmallRedExplosion(Vector3 center)
        {
            ExplosionPSystem expl = explPSystemFactory.Get();
            if (expl != null)
            {
                explPSystems.Add(expl);
                expl.Bang(redExplTex, center, 600, 100, 0.3f, 5);
            }

            ExplSmokePSystem explS = explSmokePSystemFactory.Get();
            if (explS != null)
            {
                explSmokePSystems.Add(explS);
                explS.Bang(center, 1000, 100, 0.0f, 1);
            }

        }

        public void BigRedExplosion(Vector3 center)
        {
            ExplosionPSystem expl = explPSystemFactory.Get();
            if (expl != null)
            {
                explPSystems.Add(expl);
                expl.Bang(redExplTex, center, 8000, 200, 2.0f, 5);
            }

            ExplSmokePSystem explS = explSmokePSystemFactory.Get();
            if (explS != null)
            {
                explSmokePSystems.Add(explS);
                explS.Bang(center, 10000, 1000, 0.0f, 1);
            }

            PointLight light = new PointLight(false, center);
            light.Diffuse = Color.OrangeRed.ToVector4();
            light.LifeTimeMs = 450;
            light.GrowSpeed = 0.01f;
            light.CollapseSpeed = 0.0025f;
            light.Attenuation012 = new Vector3(0, 0, 0.4f);
            light.Start();
            scene.Lights.Add(light);

        }

        public void BigGreenExplosion(Vector3 center, float size)
        {
            ExplosionPSystem expl = explPSystemFactory.Get();
            if (expl != null)
            {
                explPSystems.Add(expl);
                expl.Bang(greenExplTex, center, size * 200, 200, 2.0f, 4);
            }

            ExplSmokePSystem explS = explSmokePSystemFactory.Get();
            if (explS != null)
            {
                explSmokePSystems.Add(explS);
                explS.Bang(center, 10000, 1000, 0.0f, 1);
            }

            PointLight light = new PointLight(false, center);
            light.Diffuse = Color.LightGreen.ToVector4();
            light.LifeTimeMs = 450;
            light.GrowSpeed = 0.01f;
            light.CollapseSpeed = 0.0025f;
            light.Attenuation012 = new Vector3(0, 0, 0.2f);
            light.Start();
            scene.Lights.Add(light);
        }

        public void StoneSplash(Vector3 center)
        {
            ExplosionPSystem expl = explPSystemFactory.Get();
            if (expl != null)
            {
                explPSystems.Add(expl);
                expl.Bang(stoneTex, center, 200, 0, 3.0f, 6);
            }
        }

        public void FlatExplosion(Vector3 center, float particleSize, float radius)
        {
            scene.BilboardMgr.StartFireExplosion(center, (int)particleSize);
        }
    }
}
